/**
 * ReportGear(2011)
 */
package com.reportgear.report.view.grid.editor.impl;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.SwingConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import com.reportgear.core.data.SalaryHelper;
import com.reportgear.core.data.model.SalaryDataObject;
import com.reportgear.core.swing.layout.LayoutHelper;
import com.reportgear.core.swing.pane.base.EditorPane;
import com.reportgear.report.context.ReportContext;
import com.reportgear.report.model.SalaryReportModel;
import com.reportgear.report.model.cell.value.salary.SalaryItemObject;
import com.reportgear.report.model.cell.value.support.CommonSalaryItemObject;
import com.reportgear.report.view.JWorksheet;
import com.reportgear.swing.controls.JTreeComboBox;

/**
 * 薪酬项目面板<四川电信薪酬项目专用>
 * 
 * @version 1.0 2011-4-7
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since ReportGear 1.0
 */
public class SalaryItemPane extends EditorPane<SalaryItemObject> {
	/**
	 * UID
	 */
	private static final long serialVersionUID = 1094993216369990912L;
	// 薪酬项目
	private JTreeComboBox cbxItem = new JTreeComboBox();
	private SalaryItemObject itemObject;
	
	//TODO 考虑效率，不要多次取数，使用缓存
	public SalaryItemPane() {
		this.setLayout(new GridBagLayout());

		cbxItem.setPreferredSize(new Dimension(300, 24));

		this.add(new JLabel("薪酬项目", SwingConstants.LEFT), LayoutHelper.newGridBagConstraints(0, 1, 1, 1));
		this.add(cbxItem, LayoutHelper.newGridBagConstraints(1, 1, 1, 1));

		JWorksheet sheet = ReportContext.INSTANCE.getCurrentWorkSheet();
		SalaryReportModel model = (SalaryReportModel) sheet.getReportModel();

		this.refreshItems(model.getScheme());
	}

	/**
	 * 根据值查找父级节点
	 * 
	 * @param root
	 *            根节点
	 * @param co
	 *            节点数据对象
	 * @return 父级节点
	 */
	@SuppressWarnings("unchecked")
	private DefaultMutableTreeNode searchParentNode(TreeNode root, CommonSalaryItemObject co) {
		int pid = co.getParentId();
		DefaultMutableTreeNode node = null;
		DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) root;

		Enumeration e = rootNode.breadthFirstEnumeration();
		while (e.hasMoreElements()) {
			node = (DefaultMutableTreeNode) e.nextElement();
			Object o = node.getUserObject();
			if (o instanceof CommonSalaryItemObject) {
				if (((CommonSalaryItemObject) o).getSalaryItemId() == pid) {
					return node;
				}
			}
		}

		return null;
	}

	/**
	 * 根据值查找节点
	 * 
	 * @param root
	 *            根节点
	 * @param co
	 *            节点数据对象
	 * @return 节点
	 */
	@SuppressWarnings("unchecked")
	private DefaultMutableTreeNode searchNode(TreeNode root, CommonSalaryItemObject co) {
		int id = co.getId();
		DefaultMutableTreeNode node = null;
		DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) root;
		Enumeration e = rootNode.breadthFirstEnumeration();
		while (e.hasMoreElements()) {
			node = (DefaultMutableTreeNode) e.nextElement();
			Object o = node.getUserObject();
			if (o instanceof CommonSalaryItemObject) {
				if (((CommonSalaryItemObject) o).getId() == id) {
					return node;
				}
			}
		}
		
		return null;
	}

	/**
	 * 更新薪酬项目
	 * 
	 * @param scheme
	 *            薪酬体系
	 */
	private void refreshItems(int scheme) {
		List<CommonSalaryItemObject> items = this.getSalaryItemList(scheme);

		DefaultMutableTreeNode root = new DefaultMutableTreeNode("薪酬体系");
		DefaultMutableTreeNode pNode = null;

		for (CommonSalaryItemObject o : items) {
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(o);
			if ((pNode != null)
					&& ((CommonSalaryItemObject) pNode.getUserObject()).getSalaryItemId() == o.getParentId()) {
				pNode.add(node);
			} else {
				pNode = this.searchParentNode(root, o);
				if (pNode == null) {
					root.add(node);
				} else {
					pNode.add(node);
				}
			}
		}

		JTree tree = new JTree(root);
		cbxItem.setTree(tree);
	}

	/**
	 * 获取薪酬项目列表
	 * 
	 * @param scheme
	 *            薪酬体系
	 * @return 薪酬项目Id列表
	 */
	private List<CommonSalaryItemObject> getSalaryItemList(int scheme) {
		List<SalaryDataObject> sdoList = SalaryHelper.INSTANCE.getSalaryItem(scheme);

		List<CommonSalaryItemObject> items = new ArrayList<CommonSalaryItemObject>();
		for (SalaryDataObject sdo : sdoList) {
			items.add(new CommonSalaryItemObject(sdo.getInt("id"), sdo.getInt("SalaryItemID"), sdo.getInt("parentId"),
					sdo.getString("code"), sdo.getString("name")));
		}

		Collections.sort(items);

		return items;
	}

	@Override
	public void populate(SalaryItemObject value) {
		this.itemObject = value;

		JTree tree = cbxItem.getTree();
		DefaultTreeModel treeModel = (DefaultTreeModel) cbxItem.getTree().getModel();
		TreeNode root = (TreeNode) treeModel.getRoot();

		DefaultMutableTreeNode node = this.searchNode(root, value.getItem());

		if (node != null) {
			TreePath SelectedPath = new TreePath(treeModel.getPathToRoot(node));
			cbxItem.setSelectedItem(SelectedPath);
			tree.makeVisible(SelectedPath);
		}
	}

	/**
	 * 添加项目改变监听事件
	 * 
	 * @param listener
	 *            改变监听器
	 */
	public void addItemChangeListener(ActionListener listener) {
		this.cbxItem.addActionListener(listener);
	}

	@Override
	public int showDialog(Component owner) {
		throw new InternalError("还不能使用");
	}

	@Override
	public SalaryItemObject update() {
		DefaultMutableTreeNode selectNode = cbxItem.getSelectedTreeNode();
		this.itemObject.getItem().copyProperties((CommonSalaryItemObject) selectNode.getUserObject());

		return this.itemObject;
	}
}
